﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Jzy.Workflow.Form;
using Frame.Lib.Core.Base;
using Frame.Lib.Utilities;

namespace Jzy.Workflow.Task
{
    public class FlowTaskDAL : BaseDAL
    {       
        /// <summary>
        /// 获得待处理的表单
        /// </summary>
        /// <param name="userID"></param>
        /// <returns></returns>
        public List<FlowTaskInfo> GetRequiredList(int userID)
        {
            string sql = "select * from FlowTask where State=" + (int)TaskState.待处理 + " and ReceiveID = @p0 ";
            List<FlowTaskInfo> list = dbOper.Query<FlowTaskInfo>(sql, userID);
            return list;
        }

        internal List<FlowTaskInfo> GetDraftList(int userID)
        {
            string sql = "select * from FlowTask where  State=" + (int)TaskState.存草稿 + " and ReceiveID=@p0";
            List<FlowTaskInfo> list = dbOper.Query<FlowTaskInfo>(sql, userID);
            return list;
        }

        internal void DeleteDraft(List<string> taskIDs)
        {
            string ids = ConvertUtil.ConvertToDbStr(taskIDs);
            string sql = "delete from FlowForm where ID in (select FormID from FlowTask where ID in (" + ids + "))";
            dbOper.RunSql(sql);
        }

        internal List<FlowTaskInfo> GetDealtList(int userID)
        {
            string sql = "select * from FlowTask where ReceiveID = @p0 and State=@p1";
            List<FlowTaskInfo> list = dbOper.Query<FlowTaskInfo>(sql, userID, (int)TaskState.已完成);
            return list;
        }

        internal List<FlowTaskInfo> GetCanRecycleList(int userID)
        {
            string sql = "select * from FlowTask where ID in " + 
                         "(" +
                             "select ID from " +
                             "(" +
                                "select b.*,a.state as astate from FlowTask as a right outer join FlowTask as b on a.PreTaskID = b.ID " + //用右外连接是因为在会签节点并发时，其中一个任务结束时，不会产生新的任务，这时a表可能是null值。另当整个流程结束时也可能产生此效果，需要逻辑层判断表单流转是否结束.
                                "where b.ReceiveID = @p0 and (a.ReceiveID <> @p0 or (a.ReceiveID is null and b.State =" + (int)TaskState.已完成 + " ))" + //a.RecieveID其实是就等于 b.SendID,因为b是a的上一任务，即任务的发送方,a.ReceiveID is null主要是用于会签节点判断。
                             ") as task " + //如果a.ReceiveID is null 则表示a这条记录不存在，也就是b任务没有产生新的任务,如果要能回收，则要此任务状态是已完成，否则没必要回收了.
                             "group by ID having sum(isnull(astate,0))=0" + //a.state就是用于判断从b发出去的的任务有没有被处理,没被处理则可被回收
                         ")";
            List<FlowTaskInfo> tasks = dbOper.Query<FlowTaskInfo>(sql, userID);
            return tasks;
        }

      
        /// <summary>
        /// 
        /// </summary>
        /// <param name="taskID"></param>
        /// <param name="changeState">是否改变当前任务的状态，用在并发逻辑与的情况下</param>
        internal void Recycle(object taskID,bool changeState)
        {
            //有时间可以写成存储过程
            List<string> sqls = new List<string>(3);
            sqls.Add("delete from FlowTask where PreTaskID in (select ID from FlowTask where PreTaskID = @p0)");
            sqls.Add("delete from FlowTask where PreTaskID = @p0");

            if (changeState)
            {
                sqls.Add("update FlowTask set State= case when SendID = ReceiveID then " + (int)TaskState.存草稿 + " else " + (int)TaskState.待处理 + " end where ID=@p0");
            }
            

            //如果是自己拟稿，则回草稿箱，如果不是，则回到待办箱

            dbOper.RunSql(sqls.ToArray(), taskID);
                       
        }

        public List<FlowTaskInfo> GetNextTaskList(object id)
        {
            string sql = "select * from FlowTask where PreTaskID = @p0";
            List<FlowTaskInfo> tasks = dbOper.Query<FlowTaskInfo>(sql, id);
            return tasks;
        }

        /// <summary>
        /// 获取已审核的节点
        /// </summary>
        /// <param name="taskID"></param>
        /// <returns></returns>
        public List<FlowTaskInfo> GetApprovedTask(string taskID)
        {
            string sql = "select * from FlowTask where FormID =(select FormID from FlowTask where ID=@p0)";

            List<FlowTaskInfo> list = dbOper.Query<FlowTaskInfo>(sql, taskID);
            return list;
            
        }

        /// <summary>
        /// 获取当前节点
        /// </summary>
        /// <param name="taskID"></param>
        /// <returns></returns>
        public int GetNodeID(int taskID)
        {
            string sql = "select NodeID from FlowTask where ID=@p0";
            return dbOper.GetScalar<int>(sql, taskID);            
        }
    }

}
